#!/bin/sh

# 读取设置文件
function get_config(){
	while [[ "$*" != "" ]]; do
		eval ${1}='`uci get serverchan.serverchan.$1`' 2>/dev/null
		shift
	done
}

# 初始化设置信息
function read_config(){
	get_config "serverchan_enable" "lite_enable" "device_name" "sleeptime" "oui_data" "oui_dir" "reset_regularly" "debuglevel" "device_aliases" \
	"serverchan_ipv4" "ipv4_interface" "serverchan_ipv6" "ipv6_interface" "serverchan_up" "serverchan_down" "cpuload_enable" "cpuload" "temperature_enable" "temperature" "client_usage" "client_usage_max" "client_usage_disturb" "client_usage_whitelist" "web_logged" "ssh_logged" "web_login_failed" "ssh_login_failed" "login_max_num" "web_login_black" "ip_white_list" "ip_black_timeout" "port_knocking" "ip_white_timeout" "ip_port_white" "port_forward_list" \
	"regular_time" "regular_time_2" "regular_time_3" "interval_time" \
	"serverchan_sheep" "starttime" "endtime" "serverchan_whitelist" "serverchan_blacklist" "serverchan_interface" "MAC_online_list" "MAC_offline_list" \
	"up_timeout" "down_timeout" "timeout_retry_count" "thread_num" "soc_code" "server_host" "server_port" "err_enable" "err_sheep_enable" "err_device_aliases" "network_err_event" "system_time_event" "autoreboot_time" "network_restart_time" "public_ip_event" "public_ip_retry_count" \
	"jsonpath" "sckey" "corpid" "userid" "agentid" "corpsecret" "mediapath" "wxpusher_apptoken" "wxpusher_uids" "wxpusher_topicIds" "pushplus_token" "tg_token" "chat_id" \
	"gateway_info_enable" "gateway_host_url" "gateway_info_url" "gateway_logout_url" "gateway_username_id" "gateway_password_id" "gateway_username" "gateway_password"

	for str_version in "wrtbwmon" "iputils-arping" "curl" "iw"; do
		eval `echo ${str_version:0:2}"_version"`=`opkg list-installed|grep -w ^${str_version}|awk '{print $3}'` 2>/dev/null
	done
	dir="/tmp/serverchan/" && mkdir -p ${dir} && mkdir -p ${dir}/client
	tempjsonpath="/tmp/serverchan/temp.json"
	ip_blacklist_path="/usr/share/serverchan/api/ip_blacklist"
	[ ! -z "$oui_dir" ] && [ "$oui_dir" -eq "1" ] && oui_base="${dir}oui_base.txt" || oui_base="/usr/share/serverchan/oui_base.txt"
	debuglevel=`echo "$debuglevel"` && [ -z "$debuglevel" ] && logfile="/dev/null" || logfile="${dir}serverchan.log"
	serverchan_blacklist=`echo "$serverchan_blacklist"|sed 's/ /\n/g'` 2>/dev/null
	serverchan_whitelist=`echo "$serverchan_whitelist"|sed 's/ /\n/g'` 2>/dev/null
	device_aliases=`echo "$device_aliases"|sed 's/ /\n/g'|sed 's/-/ /'` 2>/dev/null
	err_device_aliases=`echo "$err_device_aliases"|sed 's/ /\n/g'` 2>/dev/null
	client_usage_whitelist=`echo "$client_usage_whitelist"|sed 's/ /\n/g'` 2>/dev/null
	ip_white_list=`echo "$ip_white_list"|sed 's/ /\n/g'` 2>/dev/null
	mark_mac_list="${MAC_online_list} ${MAC_offline_list}"
	mark_mac_list=`echo "$mark_mac_list"|sed 's/ /\n/g'|sed 's/-/ /'` 2>/dev/null
	ipv4_urllist=`cat /usr/share/serverchan/api/ipv4.list` 2>/dev/null
	ipv6_urllist=`cat /usr/share/serverchan/api/ipv6.list` 2>/dev/null
	port_forward_list=`echo "$port_forward_list"|sed 's/ /\n/g'|sed 's/,/ /g'` 2>/dev/null
	[ -z "$serverchan_ipv4" ] && serverchan_ipv4=0
	[ -z "$serverchan_ipv6" ] && serverchan_ipv6=0
	[ -z "$sleeptime" ] && sleeptime="60"
	[ -z "$ip_black_timeout" ] && ip_black_timeout="86400"
	[ -z "$ip_white_timeout" ] && ip_white_timeout="600"
	[ "$iw_version" ] && wlan_interface=`iw dev 2>/dev/null|grep Interface|awk '{print $2}'` >/dev/null 2>&1
	[ -z "$up_timeout" ] || [ "$up_timeout" -eq "0" ] && up_timeout="2"
	[ -z "$down_timeout" ] || [ "$down_timeout" -eq "0" ] && down_timeout="20";down_timeout=`expr ${down_timeout} / 2 + 1`
	[ -z "$timeout_retry_count" ] && timeout_retry_count="2";[ "$timeout_retry_count" -eq "0" ] && timeout_retry_count="1"
	[ -z "$server_port" ] && server_port="22"
	str_title_start=`jq -r '.str_title_start' ${jsonpath}`
	str_title_end=`jq -r '.str_title_end' ${jsonpath}`
	str_linefeed=`jq -r '.str_linefeed' ${jsonpath}`
	str_splitline=`jq -r '.str_splitline' ${jsonpath}`
	str_space=`jq -r '.str_space' ${jsonpath}`
	str_tab=`jq -r '.str_tab' ${jsonpath}`
	disturb_text=`jq -r '._api' ${jsonpath}`
	( echo "$lite_enable"|grep -q "content" ) && str_title_start="" && str_title_end="" && str_splitline="" && str_linefeed="" && str_tab=""
}

# 初始化
function serverchan_init(){
	enable_detection
	if [ -f "/usr/share/serverchan/errlog" ]; then
		cat /usr/share/serverchan/errlog > ${logfile}
		echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】载入上次重启前日志" >> ${logfile}
		echo "--------------------------------------------------------" >> ${logfile}
	fi
	down_oui &
	get_syslog
	set_ip_black

	rm -f ${dir}fd1 ${dir}sheep_usage ${dir}old_sheep_usage ${dir}client_usage_aliases ${dir}old_client_usage_aliases /usr/share/serverchan/errlog >/dev/null 2>&1
	[ ! -f "/usr/sbin/wrtbwmon" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【info】未安装 wrtbwmon ，流量统计不可用" >> ${logfile}
	[ -z "$ip_version" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】无法获取依赖项 iputils-arping 版本号，请确认插件是否正常运行" >> ${logfile}
	[ -z "$cu_version" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】无法获取依赖项 curl 版本号，请确认插件是否正常运行" >> ${logfile}
	[ -z "${sckey}${tg_token}${pushplus_token}${corpid}${wxpusher_apptoken}${wxpusher_uids}${wxpusher_topicIds}" -a "${jsonpath}" != "/usr/share/serverchan/api/diy.json" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】请填写正确的 key " >> ${logfile} && return 1
	local interfacelist=`getinterfacelist` && [ -z "$interfacelist" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】无法获取接口在线时间等信息，可能存在多个接口或配置错误，请确认插件是否正常运行" >> ${logfile}
	return 0
}

# 推送
function diy_send(){
	( ! echo "$lite_enable"|grep -q "content" ) && ( ! echo "$lite_enable"|grep -q "nowtime" ) && local nowtime=`date "+%Y-%m-%d %H:%M:%S"`
	! jq -r '.' ${3} >/dev/null 2>&1 && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】json 文件格式错误，这不是一个标准的 json 文件，请检查 ${3} 文件是否有特殊符号未转义或语法错误" >> ${logfile} && return 1
	local diyurl=`jq -r .url ${3}` && local diyurl=`eval echo ${diyurl}`
	local type=`jq -r '.type' ${3}` && local type=`eval echo ${type}`
	local data=`jq -r '.data' ${3}` && local data=`eval echo ${data}`
	local content_type=`jq -r '.content_type' ${3}`
	! jq "$type" ${3} > ${tempjsonpath} && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】type:{ } 字段转义变量后格式错误，请检查 type:{ } 字段内是否有特殊符号未转义或语法错误" >> ${logfile} && return 1
	
	[ $4 ] && echo '{"url":"'${diyurl}'","content_type":"'${content_type}'","type":'`jq "$type" ${3}`'}' > ${dir}debug_send_json
	[ $4 ] && echo -e "${send_title}" "${send_content}" > ${dir}debug_send_content
	[ $4 ] && cat ${tempjsonpath} > ${dir}debug_send_data
	[ $4 ] && ! jq -r '.' ${dir}debug_send_json && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】转义变量后格式错误，请检查 ${dir}debug_send_json 字段内是否有特殊符号未转义或语法错误" >> ${logfile}
	[ $4 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【debug】json 文件已保存至：${dir}debug_send_json"  >> ${logfile}
	[ $4 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【debug】推送内容预览文件保存至：${dir}debug_send_content" >> ${logfile}
	[ $4 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【debug】如果收不到信息，请检查 ${dir}debug_send_data 文件，或使用下列命令手动测试返回值 (可能需要关闭日志自动刷新方便选中)" >> ${logfile}
	[ $4 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【debug】"'curl -X POST -H "'$content_type'" -d "@'${dir}debug_send_data'" "'${diyurl}'"  ' >> ${logfile}
	
	curl -X POST -H "$content_type" -d "$data" "${diyurl}"
	[ $? -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】网络错误或 URL 错误，推送失败，curl 返回值为 ${tmp_value}" >> ${logfile} && return 1 || return 0
}

# 下载设备MAC厂商信息
function down_oui(){
	[ -f ${oui_base} ] && local logrow=$(grep -c "" ${oui_base}) || local logrow="0"
	[ $logrow -lt "10" ] && rm -f ${oui_base} >/dev/null 2>&1
	if [ ! -z "$oui_data" ] && [ "$oui_data" -ne "3" ] && [ ! -f ${oui_base} ]; then
		echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】设备MAC厂商信息不存在，重新下载" >> ${logfile}
		wget --no-check-certificate -t 3 -T 15 -O ${dir}oui.txt https://standards-oui.ieee.org/oui/oui.txt >/dev/null 2>&1
		if [ -f ${dir}oui.txt ] && [ "$oui_data" -eq "1" ]; then
			cat ${dir}oui.txt|grep "base 16"|grep -i "apple\|aruba\|asus\|autelan\|belkin\|bhu\|buffalo\|cctf\|cisco\|comba\|datang\|dell\|dlink\|dowell\|ericsson\|fast\|feixun\|\
fiberhome\|fujitsu\|grentech\|h3c\|hisense\|hiwifi\|honghai\|honghao\|hp\|htc\|huawei\|intel\|jinli\|jse\|lenovo\|lg\|liteon\|malata\|meizu\|mercury\|meru\|moto\|netcore\|\
netgear\|nokia\|omron\|oneplus\|oppo\|philips\|router_unkown\|samsung\|shanzhai\|sony\|start_net\|sunyuanda\|tcl\|tenda\|texas\|tianyu\|tp-link\|ubq\|undefine\|VMware\|\
utstarcom\|volans\|xerox\|xiaomi\|zdc\|zhongxing\|smartisan" > ${oui_base} && echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】设备MAC厂商信息下载成功" >> ${logfile} || echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】设备MAC厂商信息下载失败" >> ${logfile}
		fi
		if [ -f ${dir}oui.txt ] && [ "$oui_data" -eq "2" ]; then
			cat ${dir}oui.txt|grep "base 16" > ${oui_base} && echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】设备MAC厂商信息下载成功" >> ${logfile} || echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】设备MAC厂商信息下载失败" >> ${logfile}
		fi
		rm -f ${dir}oui.txt >/dev/null 2>&1
	fi
}

# 清理临时文件
function deltemp(){
	unset title	content ipAddress_logrow online_list online_mac mac_online_status gatewayinfo gateway_iplist
	rm -f ${dir}title ${dir}content ${dir}tmp_downlist ${dir}send_enable.lock ${tempjsonpath} ${dir}cookies.txt >/dev/null 2>&1
	[ ! -f ${dir}ipAddress ] && rm -f ${dir}client/* >/dev/null 2>&1
	LockFile unlock
	[ -f ${logfile} ] && local logrow=$(grep -c "" ${logfile}) || local logrow="0"
	[ $logrow -gt 500 ] && sed -i '1,100d' ${logfile} && echo "`date "+%Y-%m-%d %H:%M:%S"`  【清理】日志超出上限，删除前 100 条" >> ${logfile}
}

# 检测程序开关
function enable_detection(){
	[ ! "$1" ] && local time_n=1
	for i in `seq 1 $time_n`; do
		get_config serverchan_enable;[ -z "$serverchan_enable" ] || [ "$serverchan_enable" -eq "0" ] && `/etc/init.d/serverchan stop` || sleep 1
	done
}

# 获取 ip
function getip(){
	[ ! "$1" ] && return
	
	# 从接口获取 IPv4
	if [ $1 == "wanipv4" ] ;then
		[ ! -z "$ipv4_interface" ] && local wanIP=$(/sbin/ifconfig ${ipv4_interface}|awk '/inet addr/ {print $2}'|awk -F: '{print $2}'|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
		[ -z "$ipv4_interface" ] && local wanIP=$(getinterfacelist|grep '\"address\"'|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
		echo "$wanIP"
		
	# 从 URL 获取 IPv4
	elif [ $1 == "hostipv4" ] ;then
		local url_number=`echo "$ipv4_urllist"|wc -l`
		local rand_number=`rand 1 $url_number`
		function get_hostipv4()
		{
			local ipv4_URL=`echo "$ipv4_urllist"| sed -n "${1}p"|sed -e 's/\r//g'`
			[ ! -z "$ipv4_interface" ] && local tmp_hostIP=$(curl -k -s -4 --interface ${ipv4_interface} -m 5 ${ipv4_URL}) || local tmp_hostIP=$(curl -k -s -4 -m 5 ${ipv4_URL})
			[ -z "$tmp_hostIP" ] && echo "`date "+%Y-%m-%d %H:%M:%S"`  【info】IP 获取失败，当前使用的 API 为 $ipv4_URL" >> ${logfile}
			echo $tmp_hostIP|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'|head -n1
		}
		local hostIP=`get_hostipv4 ${rand_number}`
		[ -z $hostIP ] && local rand_number=`expr $rand_number + 1` && [ $rand_number -gt $url_number ] && local rand_number=1;[ -z $hostIP ] && local hostIP=`get_hostipv4 ${rand_number}`
		[ -z $hostIP ] && local rand_number=`expr $rand_number + 1` && [ $rand_number -gt $url_number ] && local rand_number=1;[ -z $hostIP ] && local hostIP=`get_hostipv4 ${rand_number}`
		[ -z $hostIP ] && [ `expr $(date +%s) - $(date -r /usr/share/serverchan/api/ipv4.list +%s)` -gt "86400" ] && wget --no-check-certificate -t 3 -T 15 -O /usr/share/serverchan/api/ipv4.list https://raw.githubusercontent.com/tty228/luci-app-serverchan/master/root/usr/share/serverchan/api/ipv4.list >/dev/null 2>&1 && ipv4_urllist=`cat /usr/share/serverchan/api/ipv4.list` 2>/dev/null && echo "`date "+%Y-%m-%d %H:%M:%S"`  【info】多次获取 IP 失败，重新同步 API 列表" >> ${logfile}
		[ ! -z $hostIP ] && echo $hostIP
		
	# 从接口获取 IPv6
	elif [ $1 == "wanipv6" ] ;then
		[ ! -z "$ipv6_interface" ] && local wanIPv6=$(ip addr show ${ipv6_interface}|grep -v deprecated|grep -A1 'inet6 [^f:]'|sed -nr ':a;N;s#^ +inet6 ([a-f0-9:]+)/.+? scope global .*? valid_lft ([0-9]+sec) .*#\2 \1#p;ta'|sort -nr|head -n1|awk '{print $2}')
		[ -z "$ipv6_interface" ] && local wanIPv6=$(ip addr show|grep -v deprecated|grep -A1 'inet6 [^f:]'|sed -nr ':a;N;s#^ +inet6 ([a-f0-9:]+)/.+? scope global .*? valid_lft ([0-9]+sec) .*#\2 \1#p;ta'|sort -nr|head -n1|awk '{print $2}')
		echo "$wanIPv6"
		
	# 从 URL 获取 IPv6
	elif [ $1 == "hostipv6" ] ;then
		local urlv6_number=`echo "$ipv6_urllist"|wc -l`
		local rand_numberv6=`rand 1 $urlv6_number`
		function get_hostipv6()
		{
			local ipv6_URL=`echo "$ipv6_urllist"| sed -n "${1}p"|sed -e 's/\r//g'`
			[ ! -z "$ipv6_interface" ] && local tmp_hostIPv6=$(curl -k -s -6 --interface ${ipv6_interface} -m 5 ${ipv6_URL}) || local tmp_hostIPv6=$(curl -k -s -6 -m 5 ${ipv6_URL})
			[ -z "$tmp_hostIPv6" ] && echo "`date "+%Y-%m-%d %H:%M:%S"`  【info】IP 获取失败，当前使用的 API 为 $ipv6_URL" >> ${logfile}
			echo $tmp_hostIPv6|grep -oE "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}"|head -n1
		}
		local hostIPv6=`get_hostipv6 ${rand_numberv6}`
		[ -z $hostIPv6 ] && local rand_numberv6=`expr $rand_numberv6 + 1` && [ $rand_numberv6 -gt $urlv6_number ] && local rand_numberv6=1;[ -z $hostIPv6 ] && local hostIPv6=`get_hostipv6 ${rand_numberv6}`
		[ -z $hostIPv6 ] && local rand_numberv6=`expr $rand_numberv6 + 1` && [ $rand_numberv6 -gt $urlv6_number ] && local rand_numberv6=1;[ -z $hostIPv6 ] && local hostIPv6=`get_hostipv6 ${rand_numberv6}`
		[ -z $hostIPv6 ] && [ `expr $(date +%s) - $(date -r /usr/share/serverchan/api/ipv4.list +%s)` -gt "86400" ] && wget --no-check-certificate -t 3 -T 15 -O /usr/share/serverchan/api/ipv6.list https://raw.githubusercontent.com/tty228/luci-app-serverchan/master/root/usr/share/serverchan/api/ipv6.list >/dev/null 2>&1 && ipv6_urllist=`cat /usr/share/serverchan/api/ipv4.list` 2>/dev/null && echo "`date "+%Y-%m-%d %H:%M:%S"`  【info】多次获取 IP 失败，重新同步 API 列表" >> ${logfile}
		[ ! -z $hostIPv6 ] && echo $hostIPv6
	fi
}

# 获取接口信息
function getinterfacelist(){
	[ `ubus list|grep -w -i "network.interface.wan"|wc -l` -ge "1" ] && ubus call network.interface.wan status && return
	local ubuslist=`ubus list|grep -i "network.interface."|grep -v "loopback"|grep -v -i "wan6"|grep -v -i "lan6"|grep -v -i "ipsec_server*"|grep -v -i "VPN*"|grep -v -i "DOCKER*"`
	[ `echo "${ubuslist}" |wc -l` -eq "1" ] && ubus call ${ubuslist} status && return
}

# 获取接口在线时间
function getinterfaceuptime(){
	getinterfacelist|grep \"uptime\"|sed $'s/\"uptime": //g'|sed $'s/\,//g'
}

# 查询 MAC 地址
function getmac(){
	# 已保存的 MAC
	[ -f "${dir}ipAddress" ] && local tmp_mac=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
	( echo "$tmp_mac"|grep -q "unknown" ) && unset tmp_mac # 为unknown时重新读取
	[ -f "${dir}tmp_downlist" ] && [ -z "$tmp_mac" ] && local tmp_mac=`cat ${dir}tmp_downlist|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
	# DHCP
	( echo "$tmp_mac"|grep -q "unknown" ) && unset tmp_mac # 为unknown时重新读取
	[ -f "/tmp/dhcp.leases" ] && [ -z "$tmp_mac" ] && local tmp_mac=`cat /tmp/dhcp.leases|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
	# arp
	[ -z "$tmp_mac" ] && local tmp_mac=`cat /proc/net/arp|grep "0x2\|0x6"|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`

	[ -z "$tmp_mac" ] && local tmp_mac="unknown"
	echo $tmp_mac |tr -d '\n\r'
}

# 查询主机名
function getname(){
	# 自定义备注
	local tmp_name=`echo "$device_aliases"|grep -i $2|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
	[ -f "${dir}ipAddress" ] && [ -z "$tmp_name" ] && local tmp_name=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1`
	# 已保存的 主机名
	( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取
	[ -f "${dir}tmp_downlist" ] && [ -z "$tmp_name" ] && local tmp_name=`cat ${dir}tmp_downlist|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1`
	# 静态地址备注名
	( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取
	[ -z "$dhcp_config" ] && dhcp_config=`uci show dhcp|grep "ip\|mac\|name"`
	for dhcp_config_str in "host" "domain"; do
		[ -z "$dhcp_config_str" ] && break # 退出整个循环
		local dhcp_ip_n=`echo "$dhcp_config"|grep -w ^dhcp.@${dhcp_config_str}.*ip=.${1}|sed -nr 's#^dhcp.(.*).ip.*#\1#gp'` 2>/dev/null
		[ ! -z "$dhcp_ip_n" ] && [ -z "$tmp_name" ] && local tmp_name=`uci get dhcp.${dhcp_ip_n}.name` 2>/dev/null
		local dhcp_mac_n=`echo "$dhcp_config"|grep -i ^dhcp.@${dhcp_config_str}.*mac=.${2}|sed -nr 's#^dhcp.(.*).mac.*#\1#gp'` 2>/dev/null
		[ ! -z "$dhcp_mac_n" ] && [ -z "$tmp_name" ] && local tmp_name=`uci get dhcp.${dhcp_ip_n}.name` 2>/dev/null
		[ ! -z "$tmp_name" ] && break
	done
	# DHCP
	( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取
	[ -f "/tmp/dhcp.leases" ] && [ -z "$tmp_name" ] && local tmp_name=`cat /tmp/dhcp.leases|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
	# 光猫
	( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取
	local tmp_name=`echo "$gatewayinfo"|grep -w ${1}|awk '{print $2}'`
	# MAC设备信息数据库
	( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取
	[ -f "$oui_base" ] && local tmp_name=$(cat $oui_base|grep -i $(echo "$2"|cut -c 1,2,4,5,7,8)|sed -nr 's#^.*16)..(.*)#\1#gp'|sed 's/ /_/g')
	[ ! -z "$oui_data" ] && [ "$oui_data" -eq "4" ] && local tmp_name=$(curl -sS "https://standards-oui.ieee.org/oui/oui.txt"|grep -i $(echo "$2"|cut -c 1,2,4,5,7,8)|sed -nr 's#^.*16)..(.*)#\1#gp'|sed 's/ /_/g')

	[ -z "$tmp_name" ] && local tmp_name="unknown"
	echo $tmp_name |tr -d '\n\r'
}

# 从光猫处获取设备信息
function getgateway(){
	[ -z "$gateway_info_enable" ] || [ "$gateway_info_enable" -ne "1" ] && return
	# 登录
	local loginfo=`curl -s -L "${gateway_host_url}" -c ${dir}cookies.txt -d "${gateway_username_id}=${gateway_username}&${gateway_password_id}=${gateway_password}"` 2>/dev/null
	[ ! -z "$loginfo" ] && local mytoken=$(echo $loginfo |sed 's/{/\n/g' | grep token |awk '/realRestart/{print $2}'| sed $'s/\'//g')
	# 获取
	[ ! -z "$mytoken" ] && local get_gateway=`curl -s -b ${dir}cookies.txt "${gateway_info_url}" -d 'token='$mytoken | jq '.[] | iterables| "\(.ip) \(.devName) \(.model)"'|sed 's/unknown//g'|sed 's/  / /g'|sed 's/ /_/g'|sed 's/_/ /'|sed 's/\"//g'`
	# 注销
	[ ! -z "$get_gateway" ] && [ ! -z "$gateway_logout_url" ] && curl -s -b ${dir}cookies.txt "${gateway_logout_url}" -d 'token='$mytoken 2>/dev/null
	[ -z "$get_gateway" ] && echo "`date "+%Y-%m-%d %H:%M:%S"`  【info】获取光猫信息失败，可能当前用户未注销或设置错误" >> ${logfile}

	echo "$get_gateway"
}

# 查询设备接口
function getinterface(){
	[ -z "${1}" ] && return
	[ "${1}" == "unknown" ] && return
	
	[ -f "${dir}ipAddress" ] && local ip_interface=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $5}'|grep -v "^$"|sort -u|head -n1`
	[ -f "${dir}tmp_downlist" ] && [ -z "$ip_interface" ] && local ip_interface=`cat ${dir}tmp_downlist|grep -w ${1}|awk '{print $5}'|grep -v "^$"|sort -u|head -n1`
	if [ -z "$ip_interface" ] && [ ! -z "$wlan_interface" ]; then
		for interface in $wlan_interface; do
			local ip_interface=`iw dev $interface station dump 2>/dev/null|grep Station|grep -i -w ${1}|sed -nr 's#^.*on (.*))#\1#gp'` >/dev/null 2>&1
			[ ! -z "$ip_interface" ] && echo "$ip_interface" && return
		done
	fi
	[ -z "$ip_interface" ] && local ip_interface=`cat /proc/net/arp|grep "0x2\|0x6"|grep -i -w ${1}|awk '{print $6}'|grep -v "^$"|sort -u|head -n1`
	echo $ip_interface |tr -d '\n\r'
}

# ping
function getping(){
	local ip_interface=`getinterface ${2}`
	[ "$iw_version" ] && [ "$ip_interface" ] && local wlan_online=`iw dev ${ip_interface} station dump 2>/dev/null|grep -i -w ${2}|grep Station` >/dev/null 2>&1
	[ "$wlan_online" ] && return 0
	for i in `seq 1 ${4}`; do
		( ! echo "$ip_ms"|grep -q "ms" ) && local interface=`cat /proc/net/arp|grep -w ${1}|awk '{print $6}'|grep -v "^$"|sort -u|head -n1` && [ ! -z "$interface" ] && local ip_ms=`arping -I ${interface} -c 20 -f -w ${3} ${1}` 2>/dev/null
		( ! echo "$ip_ms"|grep -q "ms" ) && local ip_ms=`ping -c 5 -w ${3} ${1}|grep -v '100% packet loss'` 2>/dev/null
		( ! echo "$ip_ms"|grep -q "ms" ) && sleep 1
	done
	( echo "$ip_ms"|grep -q "ms" )
}

# CPU 占用率
function getcpu(){
	local AT=$(cat /proc/stat|grep "^cpu "|awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}')
	sleep 3
	local BT=$(cat /proc/stat|grep "^cpu "|awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}')
	printf "%.01f%%" $(echo ${AT} ${BT}|awk '{print (($4-$2)/($3-$1))*100}')
}

# 获取SOC温度 （取所有传感器温度最大值）
function soc_temp(){
	# Intel
	[ -z "$soc_code" ] && local soctemp=`sensors -j 2>/dev/null|jq -r '."coretemp-isa-0000"."Package id 0"."temp1_input"'`
	# AMD
	[ -z "$soc_code" ] && [ -z "$soctemp" ] || [ "$soctemp" == "null" ] && local soctemp=`sensors -j 2>/dev/null|jq '."k10temp-pci-00c3"."Tctl"."temp1_input"'`
	[ -z "$soc_code" ] && [ -z "$soctemp" ] || [ "$soctemp" == "null" ] && local soctemp=`sensors -j 2>/dev/null|jq '."zenpower-pci-00c3"."Tctl"."temp1_input"'`
	
	# 通用（只能取最高温度，不一定是 CPU，特殊设备自行修改）
	# 将 grep °C 改为温度所在行的特别字符串，如 grep Core 0 等，就可以指定设备了
	[ -z "$soc_code" ] && [ -z "$soctemp" ] || [ "$soctemp" == "null" ] && local soctemp=`sensors 2>/dev/null|grep °C|sed -nr 's#^.*:.*\+(.*)°C .*#\1#gp'|sort -nr|head -n1`
	# 将 thermal_zone* 改为 thermal_zone0 thermal_zone1 等，就可以指定设备了
	[ -z "$soc_code" ] && [ -z "$soctemp" ] || [ "$soctemp" == "null" ] && local soctemp=`cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null|sort -nr|head -n1|cut -c-2`
	
	# Intel
	[ "$soc_code" == "pve" ] && [ ! -z "$server_host" ] || [ "$soctemp" == "null" ] && local soctemp=`ssh -i /root/.ssh/id_rsa root@${server_host} -p ${server_port} sensors -j 2>/dev/null|jq -r '."coretemp-isa-0000"."Package id 0"."temp1_input"'`
	# AMD
	[ "$soc_code" == "pve" ] && [ ! -z "$server_host" ] && [ -z "$soctemp" ] || [ "$soctemp" == "null" ] && local soctemp=`ssh -i /root/.ssh/id_rsa root@${server_host} -p ${server_port} sensors -j 2>/dev/null|jq '."k10temp-pci-00c3"."Tctl"."temp1_input"'`
	[ "$soc_code" == "pve" ] && [ ! -z "$server_host" ] && [ -z "$soctemp" ] || [ "$soctemp" == "null" ] && local soctemp=`ssh -i /root/.ssh/id_rsa root@${server_host} -p ${server_port} sensors -j 2>/dev/null|jq '."zenpower-pci-00c3"."Tctl"."temp1_input"'`
	# PVE 应该没啥特殊设备了，懒得写了
	
	[ ! -z "$soctemp" ] && echo "$soctemp" && return
	[ ! -z "$soc_code" ] && eval `echo "$soc_code"` 2>/dev/null
}

# 流量数据
function usage(){
	[ ! -f "/usr/sbin/wrtbwmon" ] || [ ! "$1" ] && return
	# 更新
	if [ $1 == "update" ] ;then
		function version_le() { test "$(echo "$@"|tr " " "\n"|sort -n|head -n 1)" == "$1"; }
		function version_ge() { test "$(echo "$@"|tr " " "\n"|sort -r|head -n 1)" == "$1"; }
		[ ! -z "$wr_version" ] && ( version_ge "${wr_version}" "1.2.0" ) && wrtbwmon -f ${dir}usage.db 2>/dev/null && return
		[ ! -z "$wr_version" ] && ( version_le "${wr_version}" "1.0.0" ) || [ -z "$wr_version" ] && wrtbwmon update ${dir}usage.db 2>/dev/null && return
	# 获取
	elif [ $1 == "get" ] ;then
		[ ! -f "${dir}usage.db" ] && [ ! "$3" ] && echo `bytes_for_humans 0` && return
		[ ! -f "${dir}usage.db" ] && [ "$3" ] && echo 0 && return
		[ -z "$total_n" ] && total_n=`cat ${dir}usage.db|head -n1|grep "total"|sed 's/,/\n/g'|awk '/total/{print NR}'` 2>/dev/null
		[ -z "$total_n" ] && total_n="6"
		[ "$2" ] && local tmptotal=`cat ${dir}usage.db|sed 's/,,,/,0,0,/g'|sed 's/,,/,0,/g'|sed 's/,/ /g'|grep -i -w ${2}|awk "{print "'$'$total_n"}"|grep -v "^$"|sort -u|head -n1` 2>/dev/null
		[ -z "$tmptotal" ] && local tmptotal="0"
		[ ! "$3" ] && echo `bytes_for_humans ${tmptotal}` || echo $tmptotal
	# 剔除
	elif [ $1 == "down" ] ;then
		[ "$2" ] && sed -i "/,${2},/d" ${dir}usage.db 2>/dev/null
	fi
}

# 流量数据单位换算
function bytes_for_humans {
	[ ! "$1" ] && return
	[ "$1" -gt 1073741824 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1073741824'}'` GB" && return
	[ "$1" -gt 1048576 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1048576'}'` MB" && return
	[ "$1" -gt 1024 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1024'}'` KB" && return
	echo "${1} bytes"
}

# 设备异常流量检测
function get_client_usage(){
	[ -z "$client_usage" ] && return
	[ "$client_usage" -ne "1" ] && return
	[ -z "$client_usage_max" ] && return
	
	[ -z "$get_client_usage_time" ] && get_client_usage_time=`date +%s`
	( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "K\|k" ) && client_usage_max=`expr ${client_usage_max%?} \* 1024`
	( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "M\|m" ) && client_usage_max=`expr ${client_usage_max%?} \* 1048576`
	( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "G\|g" ) && client_usage_max=`expr ${client_usage_max%?} \* 1073741824`
	[ -z "$client_usage_disturb" ] && client_usage_disturb="0"
	[ "$client_usage_disturb" -eq "0" ] && [ -f "${dir}ipAddress" ] && local MACLIST=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u`
	[ "$client_usage_disturb" -eq "1" ] && [ ! -z "$client_usage_whitelist" ] && local MACLIST=`echo "$client_usage_whitelist"`
	[ -z "$MACLIST" ] && return

	if [ "$((`date +%s`-$get_client_usage_time))" -ge "60" ]; then
		> ${dir}client_usage_aliases
		for mac in $MACLIST; do
			( ! cat ${dir}ipAddress|grep -q -i -w $mac|grep -v "^$"|sort -u|head -n1 ) && continue
			echo "$mac" `usage get ${mac} bytes` >> ${dir}client_usage_aliases
			[ -f "${dir}old_client_usage_aliases" ] && get_client_usage_bytes=`cat ${dir}old_client_usage_aliases|grep -i -w $mac|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` || continue
			[ -z "$get_client_usage_bytes" ] && get_client_usage_bytes="0"
			if [ "$((`usage get ${mac} bytes`-$get_client_usage_bytes))" -ge "$client_usage_max" ]; then
				local ip=`cat ${dir}ipAddress|grep -i -w $mac|awk '{print $1}'|grep -v "^$"|sort -u|head -n1`
				local ip_name=`getname ${ip} ${mac}`
				local tmp_usage=$(bytes_for_humans $(expr `usage get ${mac} bytes` - ${get_client_usage_bytes}))
				local time_up=`cat ${dir}ipAddress|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
				local ip_total=`usage get $mac` && [ ! -z "$ip_total" ] && local ip_total="${str_linefeed}${str_tab}总计流量： ${str_space}${str_space}${str_space}${str_space}${ip_total}"
				local time1=`date +%s`
				local time1=$(time_for_humans `expr ${time1} - ${time_up}`)
				if [ -z "$title" ]; then
					title="${ip_name} 流量异常"
					content="${content}${str_splitline}${str_title_start} 设备流量异常${str_title_end}${str_linefeed}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${mac}$ip_total${str_linefeed}${str_tab}一分钟内流量： ${str_space}${str_space}${tmp_usage}${str_linefeed}${str_tab}在线时间： ${str_space}${str_space}${str_space}${str_space}${time1}"
				elif ( echo "$title"|grep -q "流量异常" ); then
					title="${ip_name} ${title}"
					content="${content}${str_splitline}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${mac}$ip_total${str_linefeed}${str_tab}一分钟内流量： ${str_space}${str_space}${str_space}${tmp_usage}${str_linefeed}${str_tab}在线时间： ${str_space}${str_space}${str_space}${str_space}${time1}"
				else
					title="设备状态变化"
					content="${content}${str_splitline}${str_title_start} 设备流量异常${str_title_end}${str_linefeed}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${mac}$ip_total${str_linefeed}${str_tab}一分钟内流量： ${str_space}${str_space}${str_space}${tmp_usage}${str_linefeed}${str_tab}在线时间： ${str_space}${str_space}${str_space}${str_space}${time1}"
				fi
			fi
		done
		cat ${dir}client_usage_aliases > ${dir}old_client_usage_aliases
		get_client_usage_time=`date +%s`
	fi
}

# 时间单位换算
function time_for_humans {
	[ ! "$1" ] && return
	
	if [ "$1" -lt 60 ]; then
		echo "${1} 秒"
	elif [ "$1" -lt 3600 ]; then
		local usetime_min=`expr $1 / 60`
		local usetime_sec=`expr $usetime_min \* 60`
		local usetime_sec=`expr $1 - $usetime_sec`
		echo "${usetime_min} 分 ${usetime_sec} 秒"
	elif [ "$1" -lt 86400 ]; then
		local usetime_hour=`expr $1 / 3600`
		local usetime_min=`expr $usetime_hour \* 3600`
		local usetime_min=`expr $1 - $usetime_min`
		local usetime_min=`expr $usetime_min / 60`
		echo "${usetime_hour} 小时 ${usetime_min} 分"
	else
		local usetime_day=`expr $1 / 86400`
		local usetime_hour=`expr $usetime_day \* 86400`
		local usetime_hour=`expr $1 - $usetime_hour`
		local usetime_hour=`expr $usetime_hour / 3600`
		echo "${usetime_day} 天 ${usetime_hour} 小时"
	fi
}

# 计算字符真实长度
function length_str {
	[ ! "$1" ] && return
	
	local length_zh=`echo "$1"|awk '{print gensub(/[\u4e00-\u9FA5A-Za-z0-9_]/,"","g",$0)}'|awk -F "" '{print NF}'`
	local length_en=`echo "$1"|awk '{print gensub(/[^\u4e00-\u9FA5A-Za-z0-9_]/,"","g",$0)}'|awk -F "" '{print NF}'`
	
	echo `expr $length_zh / 3 \* 2 + $length_en`
}

# 截取字符，避免中文乱码
function cut_str {
	[ ! "$1" ] && return
	[ ! "$2" ] && return
	
	[ `length_str $1` -le "$2" ] && echo "$1" && return
	local temp_length=$2
	while [ $(length_str `echo "$1"|cut -c -$temp_length`) -lt "$2" ]; do
		temp_length=`expr $temp_length + 1`
	done
	while [ $(printf "%d" \'`echo "$1"|cut -c $temp_length`) -ge "128" ] && [ $(printf "%d" \'`echo "$1"|cut -c $temp_length`) -lt "224" ]; do
		temp_length=`expr $temp_length + 1`
	done
	temp_length=`expr $temp_length - 1`
	
	echo $(echo "$1"|cut -c -$temp_length)"..."
}

# 随机数
function rand(){
    local min=$1
    local max=$(($2- $min + 1))
    local num=$(date +%s%N)
    echo $(($num % $max + $min))
}

# 在线设备列表
function serverchan_first(){
	[ -f "${dir}ipAddress" ] && local IPLIST=`cat ${dir}ipAddress|awk '{print $1}'|grep -v "^$"|sort -u`
	for ip in $IPLIST; do
		read -u 5
		{
			down $ip
			echo "" >&5
		}&
	done
	wait
	unset ip IPLIST
	
	local IPLIST=`cat /proc/net/arp|grep "0x2\|0x6"|awk '{print $1}'|grep -v "^169.254."|grep -v "^$"|sort -u|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'`
	gatewayinfo=`getgateway`
	local gateway_iplist=`echo "${gatewayinfo}"|awk '{print $1}'`
	[ ! -z "$gateway_iplist" ] && local IPLIST=`echo -e "${IPLIST}\n${gateway_iplist}"|grep -v "^$"|sort -u`
	for ip in $IPLIST; do
		read -u 5
		{
			up $ip
			echo "" >&5
		}&
	done
	
	wait
}

# 创建计划任务
function serverchan_cron(){
	function del_cron(){
		( echo `crontab -l 2>/dev/null`|grep -q "serverchan" ) && crontab -l > conf && sed -i "/serverchan/d" conf && crontab conf && rm -f conf >/dev/null 2>&1
	}
	function re_cron(){
		/etc/init.d/cron stop
		/etc/init.d/cron start
	}
	del_cron
	if [ -z "$serverchan_enable" ]; then
		re_cron
		return
	fi

	# 重置流量
	if [ ! -z "$reset_regularly" ] && [ "$reset_regularly" -eq "1" ]; then
		crontab -l 2>/dev/null > conf && echo -e "0 0 * * * rm /tmp/serverchan/usage.db >/dev/null 2>&1" >> conf && crontab conf && rm -f conf >/dev/null 2>&1
		crontab -l 2>/dev/null > conf && echo -e "0 0 * * * rm /tmp/serverchan/usage6.db >/dev/null 2>&1" >> conf && crontab conf && rm -f conf >/dev/null 2>&1
	fi
	[ ! -z "$regular_time_2" ] && local regular_time_2=",${regular_time_2}"
	[ ! -z "$regular_time_3" ] && local regular_time_3=",${regular_time_3}"
	# 定时发送
	if [ ! -z "$regular_time" ] || [ ! -z "$regular_time_2" ] || [ ! -z "$regular_time_3" ]; then
		crontab -l 2>/dev/null > conf && echo -e "0 $regular_time$regular_time_2$regular_time_3 * * * /usr/share/serverchan/serverchan send &" >> conf && crontab conf && rm -f conf >/dev/null 2>&1
	# 间隔发送
	elif [ ! -z "$interval_time" ]; then
		crontab -l 2>/dev/null > conf && echo -e "0 */$interval_time * * * /usr/share/serverchan/serverchan send &" >> conf && crontab conf && rm -f conf >/dev/null 2>&1
	fi
	
	re_cron
}

# 免打扰检测
function serverchan_disturb(){
	[ -z "$serverchan_sheep" ] || [ -z "$starttime" ] || [ -z "$endtime" ] && return 0
	
	# 非免打扰时间
	if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ]; then
		unset sheep_starttime
		rm -f ${dir}sheep_usage ${dir}old_sheep_usage  2>/dev/null
		disturb_text=`jq -r '._api' ${jsonpath}`
		return 0
	# 免打扰
	else
		[ -z "$sheep_starttime" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【免打扰】夜深了，该休息了" >> ${logfile} && sheep_starttime=`date +%s`
		# 挂起
		if [ "$serverchan_sheep" -eq "1" ] ;then
			while [ `date +%H` -lt "$endtime" ]; do
				enable_detection
				sleep $sleeptime
			done
		# 静默
		elif  [ "$serverchan_sheep" -eq "2" ] ;then
			disturb_text="【免打扰】"
			return 1
		fi
	fi
}

# 文件锁
function LockFile(){
	if [ $1 = "lock" ] ;then
		[ ! -f "${dir}serverchan.lock" ] && > ${dir}serverchan.lock && return
		while [ -f "${dir}serverchan.lock" ]; do
			enable_detection 1
		done
		LockFile lock
	fi
	[ $1 = "unlock" ] && rm -f ${dir}serverchan.lock >/dev/null 2>&1
	return 0
}

# 检测黑白名单
function blackwhitelist(){
	[ ! "$1" ] && return 1
	
	[ -z "$serverchan_whitelist" ] && [ -z "$serverchan_blacklist" ] && [ -z "$serverchan_interface" ] && [ -z "$MAC_online_list" ] && [ -z "$MAC_offline_list" ] && return 0
	[ ! -z "$serverchan_whitelist" ] && ( echo "$serverchan_whitelist"|grep -q -i -w $1 ) && return 1
	[ ! -z "$serverchan_blacklist" ] && ( ! echo "$serverchan_blacklist"|grep -q -i -w $1 ) && return 1
	[ ! -z "$serverchan_interface" ] && ( ! echo `getinterface ${1}`|grep -q -i -w $serverchan_interface ) && return 1
	[ ! -z "$MAC_online_list" ] && [ ! -z "$mac_online_status" ] && return 1
	[ ! -z "$MAC_online_list" ] && ( echo "$MAC_online_list"|grep -q -i -w $1 ) && return 1
	[ ! -z "$MAC_offline_list" ] && [ -z "$mac_online_status" ] && return 1
	
	return 0
}

# 重启网络服务
function network_restart(){
cat>${dir}network_restart<<EOF
#!/bin/sh
/etc/init.d/network restart >/dev/null 2>&1 &
/etc/init.d/firewall restart >/dev/null 2>&1 &
/etc/init.d/dnsmasq restart >/dev/null 2>&1 &
EOF
	chmod 0755 ${dir}network_restart && ${dir}network_restart
	rm -f ${dir}network_restart >/dev/null 2>&1
}

# 查看无人值守任务设备是否在线
function geterrdevicealiases(){
	[ -z "$err_device_aliases" ] && return
	[ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0";[ $logrow -eq "0" ] && return
	
	local MACLIST=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u`
	for mac in $MACLIST; do
		[ -z "$err_mac" ] && [ ! -z "$mac" ] && local err_mac=`echo "$err_device_aliases"|grep -i $mac|grep -v "^$"|sort -u|head -n1`
	done
	# 进入免打扰时间已经超过一小时
	if [ ! -z "$sheep_starttime" ] && [ "$((`date +%s`-$sheep_starttime))" -ge "3600" ]; then
		> ${dir}sheep_usage
		local MACLIST=`echo "$err_device_aliases"|grep -v "^$"|sort -u`
		for mac in $MACLIST; do
			[ ! -z "$mac" ] && local tmptotal=`usage get ${mac} bytes`
			[ ! -z "$tmptotal" ] && awk 'BEGIN{printf "%.0f\n",'$tmptotal'/'204800'}' 2>/dev/null >> ${dir}sheep_usage
		done
		old_sheep_usage=`cat ${dir}old_sheep_usage` 2>/dev/null
		sheep_usage=`cat ${dir}sheep_usage` 2>/dev/null
		[ "$old_sheep_usage" == "$sheep_usage" ] && [ -z "$sheep_nousage_starttime" ] && sheep_nousage_starttime=`date +%s`
		[ "$old_sheep_usage" != "$sheep_usage" ] && unset sheep_nousage_starttime && cat ${dir}sheep_usage 2>/dev/null > ${dir}old_sheep_usage
		[ ! -z "$sheep_nousage_starttime" ] && [ "$((`date +%s`-$sheep_nousage_starttime))" -ge "300" ] && unset err_mac
	fi
	[ -z "$err_mac" ]
}

# 无人值守任务
function unattended(){
	[ -z "$err_enable" ] || [ "$err_enable" -ne "1" ] && return
	[ ! -z "$err_sheep_enable" ] && [ "$err_sheep_enable" -eq "1" ] && [ -z "$sheep_starttime" ] && return
	geterrdevicealiases;[ $? -eq "1" ] && return

	if [ ! -z "$system_time_event" ]; then
		local interfaceuptime=`getinterfaceuptime`
		if [ ! -z "$autoreboot_time" ] && [ `cat /proc/uptime|awk -F. '{run_hour=$1/3600;printf("%d",run_hour)}'` -ge "$autoreboot_time" ] && [ "$system_time_event" -eq "1" ]; then
			echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重启路由器咯" >> ${logfile}
			cat ${logfile} > /usr/share/serverchan/errlog
			sleep 2 && reboot && exit
		elif [ ! -z "$network_restart_time" ] && [ ! -z "$interfaceuptime" ] && [ `echo "$interfaceuptime"|awk -F. '{run_hour=$1/3600;printf("%d",run_hour)}'` -ge "$network_restart_time" ] && [ "$system_time_event" -eq "2" ]; then
			echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重新拨号咯" >> ${logfile}
			ifup wan >/dev/null 2>&1
			sleep 60
		fi
	fi
	
	# 重拨尝试获取公网 IP、待弃用或改进
	[ -z "$public_ip_today" ] && public_ip_today=`date +"%d"`
	[ -z "$public_ip_count" ] && public_ip_count="0"
	[ $public_ip_today -ne `date +"%d"` ] && public_ip_today=`date +"%d"` && public_ip_count=1
	if [ ! -z "$public_ip_event" ] && [ ! -z "$public_ip_retry_count" ] && [ "$public_ip_count" -le "$public_ip_retry_count" ]; then
		public_ip_count=`expr $public_ip_count + 1`
		local wanIP=`getip wanipv4`
		local hostIP=`getip hostipv4`
		if [ ! -z "$wanIP" ] && [ ! -z "$hostIP" ] && ( ! echo "$wanIP"|grep -q -w ${hostIP} );then
			echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重拨尝试获取公网 ip，当前第 $public_ip_count 次 " >> ${logfile}
			ifup wan >/dev/null 2>&1
			sleep 60
			local wanIP=`getip wanipv4` && local hostIP=`getip hostipv4`
			[ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -eq "1" ] && local IPv4=${wanIP}
			[ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -eq "2" ] && local IPv4=${hostIP}
			[ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -eq "1" ] && local IPv6=`getip wanipv6`
			[ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -eq "2" ] && local IPv6=`getip hostipv6`
			[ ! -z "$wanIP" ] && [ ! -z "$hostIP" ] && ( ! echo "$wanIP"|grep -q -w ${hostIP} ) && echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $last_IPv6 >> ${dir}ip
		fi
	fi
}

# 检测网络状态
function rand_geturl(){
	# 获取网络状态
	function getcheck(){
		local urllist="https://www.163.com https://www.qq.com https://www.baidu.com https://www.qidian.com https://www.douban.com"
		local url_number=`expr $(echo "$urllist"|grep -o ' '|wc -l) + 1`
		local url_str=`echo "$urllist"|awk -v i=$(rand 1 $url_number) '{print $i}'`
		echo `curl -k -s -w "%{http_code}" -m 5 ${url_str} -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.58" -o /dev/null`
	}
	local check=`getcheck`
	while [ -z "$check" ] || [[ $check -ne 200 && $check -ne 202 && $check -ne 301 && $check -ne 302 ]]; do
		local check=`getcheck`
		if [ ! -z "$check" ] && [[ $check -eq 200 || $check -eq 202 || $check -eq 301 || $check -eq 302 ]]; then
			[ ! -z "$network_enable" ] && [ "$network_enable" -eq "404" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【网络状态】网络恢复正常.." >> ${logfile}
			local network_enable="200"
		else
			[ -z "$network_enable" ] || [ "$network_enable" -eq "200" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】当前网络不通！停止检测！ " >> ${logfile}
			local network_enable="404"
			# 无人值守、待弃用或改进
			[ -z "$network_err_time" ] && network_err_time=`date +%s`
			if [ ! -z "$network_err_event" ] && [ "$((`date +%s`-$network_err_time))" -ge "600" ]; then
				> ${dir}send_enable.lock && serverchan_first && deltemp
				geterrdevicealiases
				if [ "$?" -eq "0" ]; then
					[ -f /usr/share/serverchan/autoreboot_count ] && retry_count=`cat /usr/share/serverchan/autoreboot_count` && rm -f /usr/share/serverchan/autoreboot_count >/dev/null 2>&1
					[ ! -z ${retry_count} ] && retry_count=0;retry_count=`expr $retry_count + 1`
					if [ "$network_err_event" -eq "1" ] ;then
						if [ "$retry_count" -lt "3" ] ;then
							echo "$retry_count" > /usr/share/serverchan/autoreboot_count
							echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】正在尝试重启路由，当前第 $retry_count 次 " >> ${logfile}
							cat ${logfile} > /usr/share/serverchan/errlog
							sleep 2 && reboot && exit
						fi
						[ "$retry_count" -eq "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】已经重启路由2次，修复失败，请主人自行修复哦" >> ${logfile}
					elif [ "$network_err_event" -eq "2" ] ;then
						[ "$retry_count" -lt "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】正在尝试重启网络，当前第 $retry_count 次 " >> ${logfile} && ifup wan >/dev/null 2>&1
						[ "$retry_count" -eq "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】已经重启网络2次，修复失败，请主人自行修复哦 " >> ${logfile}
					elif [ "$network_err_event" -eq "3" ] ;then
						if [ "$retry_count" -eq "1" ] ;then
							echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】正在尝试修复网络，当前第 1 次，重启网络服务中 " >> ${logfile} && network_restart
						elif [ "$retry_count" -eq "2" ] ;then
							echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】正在尝试修复网络，当前第 2 次，关闭可能造成网络断开的软件" >> ${logfile}
							[ `uci get koolproxy.@global[0].enabled 2>/dev/null` -eq "1" ] && [ `uci get koolproxy.@global[0].koolproxy_mode 2>/dev/null` -eq "1" ] && /etc/init.d/koolproxy stop >/dev/null 2>&1
							[ `uci get adbyby.@adbyby[0].enable 2>/dev/null` -eq "1" ] && [ `uci get adbyby.@adbyby[0].wan_mode 2>/dev/null` -eq "0" ] && /etc/init.d/adbyby stop >/dev/null 2>&1
							[ `uci get passwall.@global[0].enabled 2>/dev/null` -eq "1" ] && [ `uci get passwall.@global[0].proxy_mode 2>/dev/null|grep global` ] && /etc/init.d/koolproxy stop >/dev/null 2>&1
							local shadowsocksr_enabled=`uci get shadowsocksr.@global[0].global_server 2>/dev/null|grep nil`
							local shadowsocksr_run_mode=`uci get shadowsocksr.@global[0].run_mode 2>/dev/null|grep all`
							[ -z "$shadowsocksr_enabled" ] && [ ! -z "$shadowsocksr_run_mode" ] && /etc/init.d/shadowsocksr stop >/dev/null 2>&1
							sleep 60 && network_restart
						elif [ "$retry_count" -eq "3" ] ;then
							echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】正在尝试修复网络，当前第 3 次，备份设置项，并修改相关设置" >> ${logfile}
							mkdir -p /usr/share/serverchan/configbak
							cp -p -f /etc/config/network /usr/share/serverchan/configbak/network
							cp -p -f /etc/config/dhcp /usr/share/serverchan/configbak/dhcp
							cp -p -f /etc/config/firewall /usr/share/serverchan/configbak/firewall
							cp -p -f /etc/firewall.user /usr/share/serverchan/configbak/firewall.user
							uci set network.wan.peerdns='0'
							uci delete network.wan.dns
							uci add_list network.wan.dns='223.5.5.5'
							uci add_list network.wan.dns='119.29.29.29'
							uci delete network.wan.mtu
							uci commit network
							uci set dhcp.@dnsmasq[0].port='53'
							uci set dhcp.@dnsmasq[0].resolvfile='/tmp/resolv.conf.auto'
							uci delete dhcp.@dnsmasq[0].server
							uci delete dhcp.@dnsmasq[0].noresolv
							uci commit dhcp
							uci delete firewall.redirect
							>/etc/firewall.user
							uci commit firewall
							sleep 60 && network_restart
						elif [ "$retry_count" -eq "4" ] ;then
							echo "$retry_count" > /usr/share/serverchan/autoreboot_count
							cat ${logfile} > /usr/share/serverchan/errlog
							sleep 2 && reboot && exit
						elif [ "$retry_count" -eq "5" ] ;then
							echo "$retry_count" > /usr/share/serverchan/autoreboot_count
							echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！！】修复失败，还原设置中，请自行检查网络设置" >> ${logfile}
							cp -p -f /usr/share/serverchan/configbak/network /etc/config/network
							cp -p -f /usr/share/serverchan/configbak/dhcp /etc/config/dhcp
							cp -p -f /usr/share/serverchan/configbak/firewall /etc/config/firewall
							cp -p -f /usr/share/serverchan/configbak/firewall.user /etc/firewall.user
							cat ${logfile} > /usr/share/serverchan/errlog
							sleep 2 && reboot && exit
						fi
					fi
				fi
			elif [ -f /usr/share/serverchan/autoreboot_count ]; then
				network_err_time=`expr $network_err_time - 600` && sleep 60
			fi
			enable_detection
			sleep $sleeptime
		fi
	continue
	done
	rm -f /usr/share/serverchan/autoreboot_count >/dev/null 2>&1
}

# 检测 ip 状况
function ip_changes(){
	[ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -eq "1" ] && local IPv4=`getip wanipv4`
	[ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -eq "2" ] && local IPv4=`getip hostipv4`
	[ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -eq "1" ] && local IPv6=`getip wanipv6`
	[ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -eq "2" ] && local IPv6=`getip hostipv6`
	
	# 存在临时文件
	if [ -f ${dir}ip ]; then
		local last_IPv4=$(cat "${dir}ip"|grep IPv4|awk '{print $2}'|grep -v "^$"|sort -u|head -n1)
		local last_IPv6=$(cat "${dir}ip"|grep IPv6|awk '{print $2}'|grep -v "^$"|sort -u|head -n1)
		if [ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -ne "0" ] && [ ! -z "$IPv4" ] && ( ! echo ${IPv4}|grep -w -q ${last_IPv4} ); then
			echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前IP：${IPv4}" >> ${logfile}
			echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $last_IPv6 >> ${dir}ip
			title="IP 地址变化"
			content="${content}${str_splitline}${str_title_start} IP 地址变化${str_title_end}${str_linefeed}${str_tab}当前 IP：${IPv4}"
		fi

		if [ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -ne "0" ] && [ ! -z "$IPv6" ] && ( ! echo "$IPv6"|grep -w -q ${last_IPv6} ); then
			echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前IPv6：${IPv6}" >> ${logfile}
			echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $IPv6 >> ${dir}ip
			[ -z "$title" ] && title="IPv6 地址变化"
			[ ! -z "$title" ] && title="IP 地址变化"
			content="${content}${str_splitline}${str_title_start} IPv6 地址变化${str_title_end}${str_linefeed}${str_tab}当前 IPv6：${IPv6}"
		fi

	# 临时文件目录为空
	else
		echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}路由器已经重启!" >> ${logfile}
		[ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"`  当前IP: ${IPv4}" >> ${logfile}
		[ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"`  当前IPv6: ${IPv6}" >> ${logfile}
		echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $IPv6 >> ${dir}ip
		title="路由器重新启动"
		content="${content}${str_splitline}${str_title_start} 路由器重新启动${str_title_end}"
		[ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -ne "0" ] && content="${content}${str_linefeed}${str_tab}当前IP：${IPv4}"
		[ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -ne "0" ] && content="${content}${str_linefeed}${str_tab}当前IPv6：${IPv6}"
	fi

	# IP 变化，悄咪咪的重启 ddns 和 zerotier
	if [ ! -z "$content" ] ;then
		[ -z "$ddns_enabled" ] && ddns_enabled=$(uci show ddns|grep "enabled"|grep "1")
		[ -z "$ddns_enabled" ] && ddns_logrow=0 || ddns_logrow=$(echo "$ddns_enabled"|wc -l)
		if [ $ddns_logrow -ge 1 ]; then
			/etc/init.d/ddns restart >/dev/null 2>&1
		fi
		[ -z "$zerotier_enabled" ] && zerotier_enabled=$(uci get zerotier.sample_config.enabled)
		if [ ! -z "$zerotier_enabled" ] && [ $zerotier_enabled -eq "1" ] ; then
			/etc/init.d/zerotier restart >/dev/null 2>&1
		fi
	fi
}

# 检测设备上线
function up(){
	[ -f ${dir}ipAddress ] && ( cat ${dir}ipAddress|grep -q -w $1 ) && return
	
	local ip_mac=`getmac $1`
	local ip_name=`getname ${1} ${ip_mac}`
	local ip_interface=`getinterface ${ip_mac}`
	getping ${1} ${ip_mac} ${up_timeout} "1";local ping_online=$?
	
	# 连通
	if [ "$ping_online" -eq "0" ]; then
		LockFile lock
		[ ! -z "$serverchan_blacklist" ] && local tmp_mac=`echo "${serverchan_blacklist}"|grep -w -i ${ip_mac}`
		[ ! -z "$serverchan_whitelist" ] && local tmp_mac=`echo "${serverchan_whitelist}"|grep -w -i ${ip_mac}`
		echo "{'ip': '${1}','mac': '${ip_mac}','name': '${ip_name}','uptime': '0秒','interface': '${ip_interface}','usage': '0 bytes'}" > ${dir}client/${1}
		# ？？？
		if [ ! -z "$tmp_mac" ] && ( cat ${dir}ipAddress|grep -q -w -i ${tmp_mac} ); then
			usage down ${1}
			echo "${1} ${ip_mac} ${ip_name} `date +%s` ${ip_interface}" >> ${dir}ipAddress
			LockFile unlock && return
		# ？？？
		elif [ ! -z "$tmp_mac" ] && [ -f "${dir}tmp_downlist" ] && ( cat ${dir}tmp_downip|grep -q -w -i ${tmp_mac} ); then
			local tmp_downip=`cat ${dir}tmp_downlist|grep -w -i ${tmp_mac}|awk '{print $1}'|grep -v "^$"|sort -u|head -n1`
			usage down $tmp_downip
			sed -i "/^${tmp_downip} /d" ${dir}tmp_downlist
			LockFile unlock && return
		fi
		# 从离线二次验证区恢复信息
		[ -f "${dir}tmp_downlist" ] && local tmp_downip=`cat ${dir}tmp_downlist|grep -w ${1}|grep -v "^$"|sort -u|head -n1`
		if [ ! -z "$tmp_downip" ]; then
			cat ${dir}tmp_downlist|grep -w ${1}|grep -v "^$"|sort -u|head -n1 >> ${dir}ipAddress
			sed -i "/^${1} /d" ${dir}tmp_downlist
		# up
		else
			usage down $1
			echo "$1 ${ip_mac} ${ip_name} `date +%s` ${ip_interface}" >> ${dir}ipAddress
			blackwhitelist ${ip_mac};local ip_blackwhite=$?
			[ -f "${dir}send_enable.lock" ] || [ -z "$serverchan_up" ] || [ -z "$ip_blackwhite" ] && LockFile unlock && return
			[ ! -z "$serverchan_up" ] && [ "$serverchan_up" -ne "1" ] && LockFile unlock && return
			[ -z "$ip_blackwhite" ] || [ "$ip_blackwhite" -ne "0" ] && LockFile unlock && return
			
			[ -f "${dir}title" ] && local title=`cat ${dir}title`
			[ -f "${dir}content" ] && local content=`cat ${dir}content`
			if [ -z "$title" ]; then
				local title="$ip_name 连接了你的路由器"
				local content="${str_splitline}${str_title_start} 新设备连接${str_title_end}${str_linefeed}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${1}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${ip_mac}${str_linefeed}${str_tab}网络接口：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_interface}"
			elif ( echo ${title}|grep -q "连接了你的路由器" ); then
				local title="${ip_name} ${title}"
				local content="${str_splitline}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${1}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${ip_mac}${str_linefeed}${str_tab}网络接口：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_interface}"
			else
				local title="设备状态变化"
				local content="${str_splitline}${str_title_start} 新设备连接${str_title_end}${str_linefeed}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${1}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${ip_mac}${str_linefeed}${str_tab}网络接口：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_interface}"
			fi
			echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}新设备 ${ip_name} ${1} 连接了">> ${logfile}
			#[ ! -z "$serverchan_blacklist" ] && local title="你偷偷关注的设备上线了"
			[ ! -z "$title" ] && echo "$title" >${dir}title
			[ ! -z "$content" ] && echo -n "$content" >>${dir}content
		fi
	fi
	LockFile unlock
}

# 检测设备离线
function down(){
	local ip_mac=`getmac $1`
	local ip_name=`getname ${1} ${ip_mac}`
	local ip_interface=`getinterface ${ip_mac}`
	
	getping ${1} ${ip_mac} ${down_timeout} ${timeout_retry_count};local ping_online=$?
	# 离线，置入二次验证区
	if [ "$ping_online" -eq "1" ]; then
		LockFile lock
		[ ! -f "${dir}send_enable.lock" ] && cat ${dir}ipAddress|grep -w ${1}|grep -v "^$"|sort -u|head -n1 >> ${dir}tmp_downlist
		sed -i "/^${1} /d" ${dir}ipAddress
		rm -f ${dir}client/${1} >/dev/null 2>&1
		LockFile unlock
	# 更新主机名或 MAC
	else
		local tmp_name=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1`
		local tmp_mac=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
		if [ ${ip_name} != ${tmp_name} ] || [ ${ip_mac} != ${tmp_mac} ]; then
			LockFile lock
			local tmp_str=$(echo "$1 ${ip_mac} ${ip_name} `cat ${dir}ipAddress|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1` ${ip_interface}")
			sed -i "/^${1} /d" ${dir}ipAddress
			echo "$tmp_str" >> ${dir}ipAddress
			LockFile unlock
		fi
		local time_up=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
		local time1=`date +%s`
		local time1=$(time_for_humans `expr ${time1} - ${time_up}`)
		echo "{'ip': '${1}','mac': '${ip_mac}','name': '${ip_name}','uptime': '${time1}','interface': '${ip_interface}','usage': '`usage get $ip_mac`'}" > ${dir}client/${1}
	fi
}

# 设备离线通知
function down_send(){
	[ ! -f "${dir}tmp_downlist" ] && return
	
	local IPLIST=`cat ${dir}tmp_downlist|awk '{print $1}'`
	for ip in $IPLIST; do
		local ip_mac=`getmac ${ip}`
		blackwhitelist ${ip_mac};local ip_blackwhite=$?
		[ -z "$serverchan_down" ] || [ -z "$ip_blackwhite" ] && continue
		[ ! -z "$serverchan_down" ] && [ "$serverchan_down" -ne "1" ] && continue
		[ -z "$ip_blackwhite" ] || [ "$ip_blackwhite" -ne "0" ] && continue
		[ ! -z "$serverchan_blacklist" ] && local tmp_mac=`echo "${serverchan_blacklist}"|grep -w -i ${ip_mac}`
		[ ! -z "$serverchan_whitelist" ] && local tmp_mac=`echo "${serverchan_whitelist}"|grep -w -i ${ip_mac}`
		[ ! -z "$tmp_mac" ] && ( cat ${dir}ipAddress|grep -q -w -i ${tmp_mac} ) && continue
		
		local ip_name=`getname ${ip} ${ip_mac}`
		local time_up=`cat ${dir}tmp_downlist|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
		local ip_total=`usage get $ip_mac` && [ ! -z "$ip_total" ] && local ip_total="${str_linefeed}${str_tab}总计流量： ${str_space}${str_space}${str_space}${str_space}${ip_total}"
		local time1=`date +%s`
		local time1=$(time_for_humans `expr ${time1} - ${time_up}`)
		if [ -z "$title" ]; then
			title="${ip_name} 断开连接"
			content="${content}${str_splitline}${str_title_start} 设备断开连接${str_title_end}${str_linefeed}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${ip_mac}$ip_total${str_linefeed}${str_tab}在线时间： ${str_space}${str_space}${str_space}${str_space}${time1}"
		elif ( echo "$title"|grep -q "断开连接" ); then
			title="${ip_name} ${title}"
			content="${content}${str_splitline}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${ip_mac}$ip_total${str_linefeed}${str_tab}在线时间： ${str_space}${str_space}${str_space}${str_space}${time1}"
		else
			title="设备状态变化"
			content="${content}${str_splitline}${str_title_start} 设备断开连接${str_title_end}${str_linefeed}${str_tab}客户端名：${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP： ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC：${str_space}${str_space}${str_space}${str_space}${ip_mac}$ip_total${str_linefeed}${str_tab}在线时间： ${str_space}${str_space}${str_space}${str_space}${time1}"
		fi
		echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}设备 ${ip_name} ${ip} 断开连接 " >> ${logfile}
	done
	
	rm -f ${dir}tmp_downlist >/dev/null 2>&1
}

# 当前设备列表
function current_device(){
	( echo "$lite_enable"|grep -q "content" ) || ( echo "$lite_enable"|grep -q "device" ) && return
	[ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0";[ $logrow -eq "0" ] && return
	
	[ -f ${dir}usage.db ] && local ip_total_db="总计流量${str_space}${str_space}${str_space}${str_space}"
	content="${content}${str_splitline}${str_title_start} 现有在线设备 ${logrow} 台，具体如下${str_title_end}${str_linefeed}${str_tab}IP 地址${str_space}${str_space}${str_space}${str_space}${str_space}${str_space}${str_space}${str_space}${str_space}${ip_total_db}客户端名"
	local IPLIST=`cat ${dir}ipAddress|awk '{print $1}'`
	for ip in $IPLIST; do
		local ip_mac=`getmac ${ip}`
		local ip_total=`usage get ${ip_mac}`
		local ip_name=`getname ${ip} ${ip_mac}`
		local ip_name=`cut_str $ip_name 15`
		if [ "${#ip}" -lt "15" ]; then
			local n=`expr 15 - ${#ip}`
			for i in `seq 1 $n`; do
				local ip="${ip}${str_space}"
			done
			unset i n
		fi
		if [ ! -z "$ip_total" ]; then
			local n=`expr 11 - ${#ip_total}`
			for i in `seq 1 $n`; do
				local ip_total="${ip_total}${str_space}"
			done
		fi
		content="${content}${str_linefeed}${str_tab}${ip}${ip_total}${ip_name}"
		unset i n ip_total ip_mac ip_name
	done
}

# 检测 cpu 状态
function cpu_load(){
	if [ ! -z "$temperature_enable" ] && [ "$temperature_enable" -eq "1" ] && [ ! -z "$temperature" ]; then
		[ -z "$temperature_time" ] && temperature_time=`date +%s`
		local cpu_wendu=`soc_temp`;
		[ -z "$cpu_wendu" ] && echo "`date "+%Y-%m-%d %H:%M:%S"`  【！！！】无法读取设备温度，请检查命令" >> ${logfile}

		if [ `expr $cpu_wendu \> $temperature` -eq "1" ]; then
			echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！警报！！】 CPU 温度过高: ${cpu_wendu}" >> ${logfile}
		else
			temperature_time=`date +%s`
		fi

		if [ "$((`date +%s`-$temperature_time))" -ge "300" ] && [ -z "$temperaturecd_time" ]; then
			title="CPU 温度过高！"
			temperaturecd_time=`date +%s`
			echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text} CPU 温 度过高: ${cpu_wendu}" >> ${logfile}
			content="${content}${str_splitline}${str_title_start} CPU 温度过高${str_title_end}${str_linefeed}${str_tab}CPU 温度已连续五分钟超过预设${str_linefeed}${str_tab}接下来一小 时不再提示${str_linefeed}${str_tab}当前温度：${cpu_wendu}℃"
		elif [ ! -z "$temperaturecd_time" ] && [ "$((`date +%s`-$temperaturecd_time))" -ge "3300" ] ;then
			unset temperaturecd_time
		fi
	fi

	if [ ! -z "$cpuload_enable" ] && [ "$cpuload_enable" -eq "1" ] && [ ! -z "$cpuload" ]; then
		[ -z "$cpuload_time" ] && cpuload_time=`date +%s`
		local cpu_fuzai=`cat /proc/loadavg|awk '{print $1}'` 2>/dev/null
		[ -z "$cpu_fuzai" ] && echo "`date "+%Y-%m-%d %H:%M:%S"`  【！！！】无法读取设备负载，请检查命令" >> ${logfile}

		if [ `expr $cpu_fuzai \> $cpuload` -eq "1" ]; then
			echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！警报！！】 CPU 负载过高: ${cpu_fuzai}" >> ${logfile}
			cputop log
		else
			cpuload_time=`date +%s`
		fi

		if [ "$((`date +%s`-$cpuload_time))" -ge "300" ] && [ -z "$cpucd_time" ]; then
			unset getlogtop
			if [ ! -z "$title" ] && ( echo "$title"|grep -q "过高" ); then
				title="设备报警！"
			else
				title="CPU 负载过高！"
			fi
			cpucd_time=`date +%s`
			echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text} CPU 负 载过高: ${cpu_fuzai}" >> ${logfile}
			content="${content}${str_splitline}${str_title_start} CPU 负载过高${str_title_end}${str_linefeed}${str_tab}CPU 负载已连续五分钟超过预设${str_linefeed}${str_tab}接下来一小 时不再提示${str_linefeed}${str_tab}当前负载：${cpu_fuzai}"
			cputop
		elif [ ! -z "$cpucd_time" ] && [ "$((`date +%s`-$cpucd_time))" -ge "3300" ] ;then
			unset cpucd_time
		fi
	fi
}

# CPU 占用前三
function cputop(){
	[ -z "$1" ] && content="${content}${str_splitline}${str_title_start} 当前 CPU 占用前三的进程${str_title_end}"
	local gettop=`top -bn 1|grep -v "top -bn 1"`
	for i in `seq 5 7`; do
		local top_name=`echo "${gettop}"|awk 'NR=='${i}|awk '{print ($8 ~ /\/bin\/sh|\/bin\/bash/) ? $9 : $8}'`
		local top_load=`echo "${gettop}"|awk 'NR=='${i}|awk '{print $7}'`
		local temp_top="${top_name} ${top_load}"
		[ ! -z "$1" ] && local logtop="$logtop  $temp_top"
		[ -z "$1" ] && content="${content}${str_linefeed}${str_tab}${temp_top}"
	done
	unset i
	[ ! -z "$1" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！警报！！】 CPU 占用前三: ${logtop}" >> ${logfile}
}

# 生成日志监控文件，避免后台影响 wait 语句
function get_syslog(){
	kill -9 `pgrep -f "logread -f -p notice"` 2>/dev/null
	[ -z "$web_logged" ] && [ -z "$ssh_logged" ] && [ -z "$web_login_failed" ] && [ -z "$ssh_login_failed" ] && return
	rm -f ${dir}login_monitor >/dev/null 2>&1

cat>${dir}get_syslog<<EOF
#!/bin/sh
logread -f -p notice >> ${dir}login_monitor &
EOF
	chmod 0755 ${dir}get_syslog && ${dir}get_syslog
	rm -f ${dir}get_syslog >/dev/null 2>&1
}

# 登陆提醒通知
function login_send(){
	[ -z "$web_logged" ] && [ -z "$ssh_logged" ] && [ -z "$web_login_failed" ] && [ -z "$ssh_login_failed" ] && return
	[ ! -f ${dir}login_monitor ] && return
	# 登录
	cat ${dir}login_monitor|grep -i "accepted login"|awk '{print $4" "$8" "$NF}' >> ${dir}web_login
	cat ${dir}login_monitor|grep -i "Password auth succeeded\|Pubkey auth succeeded"|awk '{print $4" "$8" "$NF}'|sed -nr 's#^(.*):.[0-9]{1,5}#\1#gp' | sed -e 's/%.*//' >> ${dir}ssh_login
	
	# 非法登录
	cat ${dir}login_monitor|grep -i "failed login"|awk '{print $NF}' >> ${dir}web_failed
	cat ${dir}login_monitor|grep -i "Bad password attempt\|Login attempt for nonexistent user from"|awk '{print $NF}'|sed -nr 's#^(.*):.[0-9]{1,5}#\1#gp'|sed -e 's/%.*//' >> ${dir}ssh_failed
	# 读取信息后清空，避免重复统计次数
	echo "" > ${dir}login_monitor
	set_ip_black

	# Web 登录提醒
	for login_ip in `cat ${dir}web_login|awk '{print $3}'|grep -v "^$"|sort -u`; do
		[ -z "$login_ip" ] && continue
		add_ip_white ${login_ip}
		local login_time=`cat ${dir}web_login|grep -w ${login_ip}|awk '{print $1}'|grep -v "^$"|sort -u|head -n1`
		local login_mode=`cat ${dir}web_login|grep -w ${login_ip}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
		echo "$ip_white_list"|grep -w -q "$login_ip" && echo "`date "+%Y-%m-%d"` ${login_time} 【info】设备 ${login_ip} 通过 Web ${login_mode} 登陆了路由器 " >> ${logfile} && continue
		if [ ! -z "$web_logged" ] && [ "$web_logged" -eq "1" ]; then
			if [ -z "$title" ]; then
				title="${login_ip} 通过 Web 登陆了路由器"
				content="${content}${str_splitline}${str_title_start} 登陆信息${str_title_end}${str_linefeed}${str_tab}时间：${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}"
			elif ( echo "$title"|grep -q "登陆了路由器" ); then
				title="${login_ip} ${title}"
				content="${content}${str_splitline}${str_tab}时间：${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}"
			else
				title="设备状态变化"
				content="${content}${str_splitline}${str_title_start} 登陆信息${str_title_end}${str_linefeed}${str_tab}时间：${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}"
			fi
		fi
		sed -i "/^${login_ip}$/d" ${dir}ssh_failed
		sed -i "/^${login_ip}$/d" ${dir}web_failed
		echo "`date "+%Y-%m-%d"` ${login_time} ${disturb_text}设备 ${login_ip} 通过 Web ${login_mode} 登陆了路由器 " >> ${logfile}
	done
	echo "" > ${dir}web_login
	unset login_ip login_time login_mode
	# SSH 登录提醒
	for login_ip in `cat ${dir}ssh_login|awk '{print $3}'|grep -v "^$"|sort -u`; do
		[ -z "$login_ip" ] && continue
		add_ip_white ${login_ip}
		local login_time=`cat ${dir}ssh_login|grep -w ${login_ip}|awk '{print $1}'|grep -v "^$"|sort -u|head -n1`
		local login_mode=`cat ${dir}ssh_login|grep -w ${login_ip}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
		echo "$ip_white_list"|grep -w -q "$login_ip" && echo "`date "+%Y-%m-%d"` ${login_time} 【info】设备 ${login_ip} 通过 SSH ${login_mode} 登陆了路由器 " >> ${logfile} && continue
		[ ! -z "$login_mode" ] && local content_mode="${str_linefeed}${str_tab}登录方式： ${str_space}${str_space}${str_space}${str_space}${login_mode}"
		if [ ! -z "$ssh_logged" ] && [ "$ssh_logged" -eq "1" ]; then
			if [ -z "$title" ]; then
				title="${login_ip} 通过 SSH 登陆了路由器"
				content="${content}${str_splitline}${str_title_start} 登陆信息${str_title_end}${str_linefeed}${str_tab}时间：${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}"
			elif ( echo "$title"|grep -q "登陆了路由器" ); then
				title="${login_ip} ${title}"
				content="${content}${str_splitline}${str_tab}时间：${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}"
			else
				title="设备状态变化"
				content="${content}${str_splitline}${str_title_start} 登陆信息${str_title_end}${str_linefeed}${str_tab}时间：${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}"
			fi
		fi
		sed -i "/^${login_ip}$/d" ${dir}ssh_failed
		echo "`date "+%Y-%m-%d"` ${login_time} ${disturb_text}设备 ${login_ip} 通过 SSH ${login_mode} 登陆了路由器 " >> ${logfile}
	done
	echo "" > ${dir}ssh_login
	unset login_ip login_time login_mode
	# Web 非法登录
	for login_ip in `cat ${dir}web_failed|awk '{print $1}'|grep -v "^$"|sort -u`; do
		[ -z "$login_ip" ] && continue
		echo "$ip_white_list"|grep -w -q "$login_ip" && continue
		local login_sum=`cat ${dir}web_failed|grep -w "${login_ip}"|wc -l`
		if [ "$login_sum" -ge "$login_max_num" ] ;then
			if [ ! -z "$web_login_failed" ] && [ "$web_login_failed" -eq "1" ]; then
				if [ -z "$title" ]; then
					title="${login_ip} 通过 Web 频繁尝试登陆"
					content="${content}${str_splitline}${str_title_start} 登陆信息${str_title_end}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}"
				elif ( echo "$title"|grep -q "频繁尝试登陆" ); then
					title="${login_ip} ${title}"
					content="${content}${str_splitline}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}"
				else
					title="设备状态变化"
					content="${content}${str_splitline}${str_title_start} 登陆信息${str_title_end}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}"
				fi
			fi
			sed -i "/^${login_ip}$/d" ${dir}web_failed
			echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】设备 ${login_ip} 通过 Web 频繁尝试登陆" >> ${logfile}
			add_ip_black $login_ip
		fi
	done
	unset login_ip login_sum
	# SSH 非法登录
	for login_ip in `cat ${dir}ssh_failed|awk '{print $1}'|grep -v "^$"|sort -u`; do
		[ -z "$login_ip" ] && continue
		echo "$ip_white_list"|grep -w -q "$login_ip" && continue
		local login_sum=`cat ${dir}ssh_failed|grep -w "${login_ip}"|wc -l`
		if [ "$login_sum" -ge "$login_max_num" ] ;then
			if [ ! -z "$ssh_login_failed" ] && [ "$ssh_login_failed" -eq "1" ]; then
				if [ -z "$title" ]; then
					title="${login_ip} 通过 SSH 频繁尝试登陆"
					content="${content}${str_splitline}${str_title_start} 登陆信息${str_title_end}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}"
				elif ( echo "$title"|grep -q "频繁尝试登陆" ); then
					title="${login_ip} ${title}"
					content="${content}${str_splitline}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}"
				else
					title="设备状态变化"
					content="${content}${str_splitline}${str_title_start} 登陆信息${str_title_end}${str_linefeed}${str_tab}设备 IP： ${str_space}${str_space}${str_space}${str_space}${login_ip}"
				fi
			fi
			sed -i "/^${login_ip}$/d" ${dir}ssh_failed
			echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】设备 ${login_ip} 通过 SSH 频繁尝试登陆" >> ${logfile}
			add_ip_black $login_ip
		fi
	done
	unset login_ip login_sum
}

# 添加白名单，懒得写删除项和信息显示了，感觉没啥必要
function add_ip_white(){
	[ ! "$1" ] && return
	[ -z "$port_knocking" ] || [ "$port_knocking" -ne "1" ] && return
	
	# 开放端口
	if ( echo ${1}|grep -q -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" ); then
		ipset list ip_whitelist >/dev/null 2>&1 || ipset create ip_whitelist hash:ip timeout ${ip_white_timeout} >/dev/null 2>&1
		# 开放端口
		iptables -C INPUT -m set --match-set ip_whitelist src -p tcp -m multiport --dport ${ip_port_white} -j ACCEPT >/dev/null 2>&1 || iptables -I INPUT -m set --match-set ip_whitelist src -p tcp -m multiport --dport ${ip_port_white} -j ACCEPT >/dev/null 2>&1
		# 端口转发
		for port_forward in `echo "$port_forward_list"`; do
			iptables -t nat -C PREROUTING -m set --match-set ip_whitelist src -p tcp --dport `echo ${port_forward}|awk '{print $2}'` -j DNAT --to-destination "`echo ${port_forward}|awk '{print $3}'`:`echo ${port_forward}|awk '{print $4}'`" >/dev/null 2>&1 || iptables -t nat -I PREROUTING -m set --match-set ip_whitelist src -p tcp --dport `echo ${port_forward}|awk '{print $2}'` -j DNAT --to-destination "`echo ${port_forward}|awk '{print $3}'`:`echo ${port_forward}|awk '{print $4}'`" >/dev/null 2>&1
			iptables -t nat -C POSTROUTING -m set --match-set ip_whitelist src -p tcp -d `echo ${port_forward}|awk '{print $3}'` --dport `echo ${port_forward}|awk '{print $4}'` -j SNAT --to-source `echo ${port_forward}|awk '{print $1}'` >/dev/null 2>&1 || iptables -t nat -I POSTROUTING -m set --match-set ip_whitelist src -p tcp -d `echo ${port_forward}|awk '{print $3}'` --dport `echo ${port_forward}|awk '{print $4}'` -j SNAT --to-source `echo ${port_forward}|awk '{print $1}'` >/dev/null 2>&1
		done
		
		unset port_forward
		ipset -exist add ip_whitelist ${1} timeout ${ip_white_timeout}
		
	elif ( echo ${1}|grep -q -oE "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}" ); then
		ipset list ip_whitelistv6 >/dev/null 2>&1 || ipset create ip_whitelistv6 hash:ip timeout ${ip_white_timeout} family inet6 >/dev/null 2>&1
		# 开放端口
		ip6tables -C INPUT -m set --match-set ip_whitelistv6 src -p tcp -m multiport --dport ${ip_port_white} -j ACCEPT >/dev/null 2>&1 || ip6tables -I INPUT -m set --match-set ip_whitelistv6 src -p tcp -m multiport --dport ${ip_port_white} -j ACCEPT >/dev/null 2>&1
		# 端口转发
		for port_forward in `echo "$port_forward_list"`; do
			ip6tables -t nat -C PREROUTING -m set --match-set ip_whitelist src -p tcp --dport `echo ${port_forward}|awk '{print $2}'` -j DNAT --to-destination "`echo ${port_forward}|awk '{print $3}'`:`echo ${port_forward}|awk '{print $4}'`" >/dev/null 2>&1 || ip6tables -t nat -I PREROUTING -m set --match-set ip_whitelist src -p tcp --dport `echo ${port_forward}|awk '{print $2}'` -j DNAT --to-destination "`echo ${port_forward}|awk '{print $3}'`:`echo ${port_forward}|awk '{print $4}'`" >/dev/null 2>&1
			ip6tables -t nat -C POSTROUTING -m set --match-set ip_whitelist src -p tcp -d `echo ${port_forward}|awk '{print $3}'` --dport `echo ${port_forward}|awk '{print $4}'` -j SNAT --to-source `echo ${port_forward}|awk '{print $1}'` >/dev/null 2>&1 || ip6tables -t nat -I POSTROUTING -m set --match-set ip_whitelist src -p tcp -d `echo ${port_forward}|awk '{print $3}'` --dport `echo ${port_forward}|awk '{print $4}'` -j SNAT --to-source `echo ${port_forward}|awk '{print $1}'` >/dev/null 2>&1
		done
		
		unset port_forward
		ipset -exist add ip_whitelistv6 ${1} timeout ${ip_white_timeout}
	fi
}

# 添加黑名单
function add_ip_black(){
	[ ! "$1" ] && return
	( ipset -q test ip_blacklist ${1} ) && continue
	( ipset -q test ip_blacklistv6 ${1} ) && continue
	
	[ "$1" ] && echo "$1 timeout ${ip_black_timeout}" >> ${ip_blacklist_path}
	# 检查并添加
	if ( echo ${1}|grep -q -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" ); then
		ipset list ip_blacklist >/dev/null 2>&1 || ipset create ip_blacklist hash:ip timeout ${ip_black_timeout} >/dev/null 2>&1
		iptables -C INPUT -m set --match-set ip_blacklist src -j DROP >/dev/null 2>&1 || iptables -I INPUT -m set --match-set ip_blacklist src -j DROP >/dev/null 2>&1
		ipset add ip_blacklist ${1} timeout ${ip_black_timeout}
	elif ( echo ${1}|grep -q -oE "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}" ); then
		ipset list ip_blacklistv6 >/dev/null 2>&1 || ipset create ip_blacklistv6 hash:ip timeout ${ip_black_timeout} family inet6 >/dev/null 2>&1
		ip6tables -C INPUT -m set --match-set ip_blacklistv6 src -j DROP >/dev/null 2>&1 || ip6tables -I INPUT -m set --match-set ip_blacklistv6 src -j DROP >/dev/null 2>&1
		ipset add ip_blacklistv6 ${1} timeout ${ip_black_timeout}
	fi
}

# 移出黑名单
function del_ip_black(){
	[ ! "$1" ] && return
	
	sed -i "/^${1}/d" ${ip_blacklist_path}
	if ( echo ${1}|grep -q -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" ); then
		ipset list ip_blacklist >/dev/null 2>&1 && ipset -! del ip_blacklist ${1}
	elif ( echo ${1}|grep -oE "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}" ); then
		ipset list ip_blacklistv6 >/dev/null 2>&1 && ipset -! del ip_blacklistv6 ${1}
	fi
}

# 设置防火墙列表
function set_ip_black(){
	# 检查换行，避免出错
	[ `tail -n1 "${ip_blacklist_path}" | wc -l` -eq "0" ] && echo -e >> ${ip_blacklist_path}
	# 如果黑名单列表为空，移除集合并退出
	if  [ ! -z "$web_login_black" ] && [ "$web_login_black" -eq "0" ] || [ -z "$web_login_black" ] || [ ! -f ${ip_blacklist_path} ] || [ -z "`cat ${ip_blacklist_path}`" ]; then
		iptables -D INPUT -m set --match-set ip_blacklist src -j DROP >/dev/null 2>&1
		ipset destroy ip_blacklist >/dev/null 2>&1
		ip6tables -D INPUT -m set --match-set ip_blacklistv6 src -j DROP >/dev/null 2>&1
		ipset destroy ip_blacklistv6 >/dev/null 2>&1
		return
	fi
	# 从 ip_blacklist 文件逐行添加黑名单，add_ip_black() 处验证是否重复
	for ip_black in `cat ${ip_blacklist_path}|awk '{print $1}'`; do
		add_ip_black ${ip_black}
	done
	# 当 ip_blacklist 文件清除 IP 时，移除防火墙规则
	for fw_ip_blacklist in `ipset list ip_blacklist 2>/dev/null|grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"`; do
		[ -z "$fw_ip_blacklist" ] && continue
		local fw_info_blacklist=`ipset list ip_blacklist 2>/dev/null|grep -w -i ${fw_ip_blacklist}`
		cat ${ip_blacklist_path}|grep -q -w -i ${fw_ip_blacklist} && sed -i "/^${fw_ip_blacklist}/d" ${ip_blacklist_path} && echo ${fw_info_blacklist} >> ${ip_blacklist_path} || del_ip_black ${fw_ip_blacklist}
	done
	for fw_ip_blacklistv6 in `ipset list ip_blacklistv6 2>/dev/null|grep -Eo "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}"`; do
		[ -z "$fw_ip_blacklistv6" ] && continue
		local fw_info_blacklistv6=`ipset list ip_blacklistv6 2>/dev/null|grep -w -i ${fw_ip_blacklistv6}`
		cat ${ip_blacklist_path}|grep -q -w -i ${fw_ip_blacklistv6} && sed -i "/^${fw_ip_blacklistv6}/d" ${ip_blacklist_path} && echo ${fw_info_blacklistv6} >> ${ip_blacklist_path} || del_ip_black ${fw_ip_blacklistv6}
	done
}

# 发送定时数据
function send(){
	echo "`date "+%Y-%m-%d %H:%M:%S"` 【定时数据】创建定时任务" >> ${logfile}
	serverchan_disturb;local send_disturb=$?
	get_config "send_title" "router_status" "router_temp" "router_wan" "client_list"

	[ -z "$send_title" ] && local send_title="路由状态："
	[ ! -z "$1" ] && local send_title="发送测试：" && local send_content="${str_splitline}${str_title_start}内容1${str_title_end}${str_linefeed}${str_tab}设备1${str_linefeed}${str_tab}设备2${str_splitline}${str_title_start}内容2${str_title_end}${str_linefeed}${str_tab}设备3${str_linefeed}${str_tab}设备4"
	[ -z "$1" ] && [ ! -z "$client_list" ] && [ "$client_list" -eq "1" ] && > ${dir}send_enable.lock && serverchan_first &

	if [ -z "$1" ] && [ ! -z "$router_status" ] && [ "$router_status" -eq "1" ]; then
		local systemload=`cat /proc/loadavg|awk '{print $1" "$2" "$3}'`
		local cpuload=`getcpu`
		local ramload=`free -m|sed -n '2p'|awk '{printf "%.2f%%\n",($3/$2)*100}'`
		local Qwai=`curl -o /dev/null --connect-timeout 5 -s -w %{http_code} www.google.com`
		if [[ $Qwai -eq 200 || $Qwai -eq 301 || $Qwai -eq 302 ]]; then
			local Qwai_status="已连通！"
		else
			local Qwai_status="已断开！"
		fi
		local systemstatustime=`cat /proc/uptime|awk -F. '{run_days=$1 / 86400;run_hour=($1 % 86400)/3600;run_minute=($1 % 3600)/60;run_second=$1 % 60;printf("运行时间：%d天%d时%d分%d秒",run_days,run_hour,run_minute,run_second)}'`;unset run_days run_hour run_minute run_second
		local send_content="${send_content}${str_splitline}${str_title_start} 系统运行状态${str_title_end}"
		local send_content="${send_content}${str_linefeed}${str_tab}平均负载：${systemload}"
		local send_content="${send_content}${str_linefeed}${str_tab}CPU占用：${cpuload}"
		local send_content="${send_content}${str_linefeed}${str_tab}内存占用：${ramload}"
		local send_content="${send_content}${str_linefeed}${str_tab}全球互联：${Qwai_status}"
		local send_content="${send_content}${str_linefeed}${str_tab}${systemstatustime}"
	fi

	if [ -z "$1" ] && [ ! -z "$router_temp" ] && [ "$router_temp" -eq "1" ]; then
		local cputemp=`soc_temp`
		[ ! -z "$cputemp" ] && local send_content="${send_content}${str_splitline}${str_title_start} 设备温度${str_title_end}${str_linefeed}${str_tab}CPU：${cputemp}℃"
		[ -z "$cputemp" ] && local send_content="${send_content}${str_splitline}${str_title_start} 设备温度${str_title_end}${str_linefeed}${str_tab}无法获取设备温度"
	fi

	if [ -z "$1" ] && [ ! -z "$router_wan" ] && [ "$router_wan" -eq "1" ]; then
		local send_wanIP=`getip wanipv4`;local send_hostIP=`getip hostipv4`
		local send_content="${send_content}${str_splitline}${str_title_start} WAN 口信息${str_title_end}${str_linefeed}${str_tab}接口 IPv4:${send_wanIP}"
		local send_content="${send_content}${str_linefeed}${str_tab}外网 IPv4:${send_hostIP}"
		if [ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -ne "0" ]; then
			local send_wanIPv6=`getip wanipv6`;local send_hostIPv6=`getip hostipv6`
			local send_content="${send_content}${str_linefeed}${str_tab}接口 IPv6:${send_wanIPv6}"
			local send_content="${send_content}${str_linefeed}${str_tab}外网 IPv6:${send_hostIPv6}"
		fi
		( ! echo "$send_wanIP"|grep -q -w ${send_hostIP} ) && local send_content="${send_content}${str_linefeed}${str_tab}外网 IP 与接口 IP 不一致，你的 IP 可能不是公网 IP"
		local interfaceuptime=`getinterfaceuptime`
		[ ! -z "$interfaceuptime" ] && local wanstatustime=`getinterfaceuptime|awk -F. '{run_days=$1 / 86400;run_hour=($1 % 86400)/3600;run_minute=($1 % 3600)/60;run_second=$1 % 60;printf("在线时间：%d天%d时%d分%d秒",run_days,run_hour,run_minute,run_second)}'` && unset run_days run_hour run_minute run_second
		local send_content="${send_content}${str_linefeed}${str_tab}${wanstatustime}"
	fi

	if [ -z "$1" ] && [ ! -z "$client_list" ] && [ "$client_list" -eq "1" ]; then
		wait
		local IPLIST=`cat ${dir}ipAddress 2>/dev/null|awk '{print $1}'`
		[ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0"
		[ "$logrow" -eq "0" ] && local send_content="${send_content}${str_splitline}${str_title_start} 当前无在线设备${str_title_end}" || local send_content="${send_content}${str_splitline}${str_title_start} 现有在线设备 ${logrow} 台${str_title_end}"
		for ip in $IPLIST; do
			local time_up=`cat ${dir}ipAddress|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
			local time1=`date +%s`
			local time1=$(time_for_humans `expr ${time1} - ${time_up}`)
			local ip_mac=`getmac ${ip}`
			local ip_name=`getname ${ip} ${ip_mac}`
			local ip_total=`usage get ${ip_mac}`;[ ! -z "$ip_total" ] && local ip_total="总计流量：${ip_total}  "
			local ip_name=`cut_str $ip_name 18`
			local send_content="${send_content}${str_linefeed}${str_tab}【${ip_name}】  ${ip}${str_linefeed}${str_tab}${ip_total}在线 ${time1}"
			unset ip_total time_down time_up time1 ip_mac ip_name
		done
	fi
	[ ! -z "$device_name" ] && local send_title="【$device_name】${send_title}"
	[ -z "$send_content" ] && local send_content="${str_splitline}${str_title_start} 我遇到了一个难题${str_title_end}${str_linefeed}${str_tab}定时发送选项错误，你没有选择需要发送的项目，该怎 么办呢${str_splitline}"
	[ "$send_disturb" -eq "0" ] && diy_send "${send_title}" "${send_content}" "${jsonpath}" "$1" >/dev/null 2>&1
	[ $? -eq 1 ] && [ "$send_disturb" -eq "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】定时推送失败，请检查网络或设置信息" >> ${logfile} || echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}定时推送任务完成" >> ${logfile}
	deltemp
}

# 初始化
read_config
deltemp
serverchan_cron

# 限制并发进程
[ -z "$thread_num" ] || [ "$thread_num" -eq "0" ] && thread_num=5
[ "$1" ] && [ $1 == "t1" ] && thread_num=1
[ -e ${dir}fd1 ] || mkfifo ${dir}fd1
exec 5<>${dir}fd1
rm -f ${dir}fd1 >/dev/null 2>&1
for i in `seq 1 $thread_num`; do
	echo >&5
done
unset i

# 启动参数
if [ "$1" ] ;then
	[ $1 == "send" ] && send
	[ $1 == "soc" ] && echo `soc_temp` > ${dir}soc_tmp
	[ $1 == "test" ] && send test
	[ $1 == "t1" ] || exit
fi

# 载入在线设备
serverchan_init;[ $? -eq 1 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【！！！】读取设置出错，请检查设置项 " >> ${logfile} && exit
echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】载入在线设备" >> ${logfile}
> ${dir}send_enable.lock && serverchan_first && deltemp
echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】初始化完成" >> ${logfile}

# 循环
while [ "$serverchan_enable" -eq "1" ]; do
	deltemp
	usage update
	serverchan_disturb;disturb=$?

	[ -f ${dir}ipAddress ] && ipAddress_logrow=$(grep -c "" ${dir}ipAddress) || ipAddress_logrow="0";
	if [ $ipAddress_logrow -ne "0" ]; then
		online_list=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u`
		for online_mac in $online_list; do
			[ ! -z "$online_mac" ] && mac_online_status="`echo "$mark_mac_list"|grep -i $online_mac|grep -v "^$"|sort -u|head -n1`${mac_online_status}"
		done
	fi
	
	# 网络状态与 IP 变动
	if [ "$serverchan_ipv4" -ne "0" ] || [ "$serverchan_ipv6" -ne "0" ]; then
		rand_geturl
		ip_changes
	fi

	# 设备列表
	if [ ! -f "${dir}send_enable.lock" ]; then
		[ ! -z "$title" ] && echo "$title" > ${dir}title
		[ ! -z "$content" ] && echo "$content" > ${dir}content
		serverchan_first
		[ -f "${dir}title" ] && title=`cat ${dir}title` && rm -f ${dir}title >/dev/null 2>&1
		[ -f "${dir}content" ] && content=`cat ${dir}content` && rm -f ${dir}content >/dev/null 2>&1
	fi

	# 离线二次验证区推送
	[ ! -f "${dir}send_enable.lock" ] && down_send

	# 当前设备列表
	[ ! -z "$content" ] && [ ! -f "${dir}send_enable.lock" ] && current_device

	# 无人值守任务
	[ ! -f "${dir}send_enable.lock" ] && unattended

	# CPU 检测
	[ ! -f "${dir}send_enable.lock" ] && cpu_load

	# 异常流量检测
	[ ! -f "${dir}send_enable.lock" ] && get_client_usage

	# 登陆提醒通知
	[ ! -f "${dir}send_enable.lock" ] && login_send
	
	# 推送
	if [ ! -f "${dir}send_enable.lock" ] && [ ! -z "$title" ] && [ ! -z "$content" ]; then
		[ ! -z "$device_name" ] && title="【$device_name】$title"
		( echo "$lite_enable"|grep -q "content" ) && content="$title"
		[ "$disturb" -eq "0" ] && diy_send "${title}" "${content}" "${jsonpath}" >/dev/null 2>&1
	fi
	
	# 等待定时任务推送完成
	while [ -f "${dir}send_enable.lock" ]; do
		sleep $sleeptime
	done

	sleep $sleeptime
done
